home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d19 / add2bbs.arc / ADD2BBS.C next >
Text File  |  1990-10-17  |  38KB  |  1,063 lines

  1. /* #define DEBUG */
  2. /*
  3.  ╔══[ MS-DOS ! ]═════════════════════════════════════════════════════════════╗
  4.  ║                                                                           ║
  5.  ║                 -  ADD2BBS.C R.Cougnenc 1990 - Public Domain -            ║
  6.  ║                                                                           ║
  7.  ╟───────────────────────────────────────────────────────────────────────────╢
  8.  ║                                                                           ║
  9.  ║    This program moves the newly downloaded files and their descriptions   ║
  10.  ║    to the specified file directory and description file.                  ║
  11.  ║                                                                           ║
  12.  ║    Files are MOVED and do not remain in the source dir.                   ║
  13.  ║                                                                           ║
  14.  ║    Specially designed for Attila ALTAN, sysop of LI'LL BBS, Paris France. ║
  15.  ║                                                                           ║
  16.  ║    Compile: Microsoft-C or Turbo-C.                                       ║
  17.  ║                                                                           ║
  18.  ║                                                                           ║
  19.  ╚═══════════════════════════════════════════════════════════════════════════╝
  20.  
  21.   The executable distribution file is compiled with MS-C, using Large Model.
  22.   This allows the use of the total memory to store the filenames to process,
  23.   and all screen outputs going to stdout.
  24.  
  25.   If you use Turbo-C, the #defines should make a program writing directly
  26.   to the screen memory, this is a lot faster, but not a good solution for
  27.   such a program.
  28.  
  29.   I took me just one day to write this program, it is certainly not
  30.   perfect...
  31.                       Feel free to correct all bugs  !
  32. */
  33.  
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <time.h>
  37. #include <fcntl.h>
  38.  
  39. #include <errno.h>
  40. #include <dos.h>
  41. #include <stdlib.h>
  42. #include <process.h>
  43. #include <io.h>
  44. #include <share.h>
  45.  
  46. #ifndef __TURBOC__
  47. #include <sys/types.h>
  48. #include <memory.h>
  49. #else
  50. #include <mem.h>
  51. #include <dir.h>
  52. #include <conio.h>
  53. #define printf cprintf
  54. #endif
  55.  
  56. #include <sys/stat.h>
  57. #include "add2bbs.h"
  58.  
  59. /*-----------------------( Global variables )-----------------------------*/
  60.  
  61. struct Ftype *Fstru  ;
  62. FILE *dfile ;
  63.  
  64. char ScanDir    [ 256 ] ,                 /* Ready for Posix :-)          */
  65.      ScanPath   [ 256 ] ,
  66.      FileDes    [ 256 ] ,
  67.      DestDir    [ 256 ] ,
  68.      FileList   [ 256 ] ,
  69.      ConfPath   [ 256 ] ,
  70.      TmpFile    [ 256 ] ,
  71.      ExtCommand [ 256 ] ,
  72.      CmTab [ MAX_C_LINES ][ MAX_C_COLS+1 ];
  73.  
  74. int nbfiles ;
  75.  
  76.  
  77. /*----------------------( main program )------------------------------------*/
  78.  
  79. int main(int argc,char **argv)
  80. {
  81.         int result;
  82.         Title();
  83.         if( argc == 1 )      /* No argument, use configuration  file */
  84.         {
  85.                 MakeConfPath(argv[0]);
  86.                 if( ! ReadConf() )
  87.                         return(0xFF);
  88.         }
  89.         else
  90.         {
  91.                 if( argc != 5 )
  92.                 {
  93.                         Usage();
  94.                         return( 0xFF);
  95.                 }
  96.                 strcpy( ScanDir  , argv[1]  );
  97.                 strcpy( FileDes  , argv[2]  );
  98.                 strcpy( DestDir  , argv[3]  );
  99.                 strcpy( FileList , argv[4]  );
  100.  
  101.         }
  102.  
  103.         if( ! VerifPath() )
  104.                 return(0xFF);
  105.  
  106.         if(! (nbfiles = FindFiles())  )
  107.         {
  108.                 printf("%s : No file found.\n",ScanDir );
  109.                 return( 0xFF );
  110.         }
  111.  
  112.         if ( (dfile = fopen( TmpFile,"a+")) == NULL )
  113.         {
  114.                 printf("Unable to open file %s !\n",FileList);
  115.                 return (0xFF);
  116.         }
  117.         ListFiles(ALL);
  118.  
  119.         if( (result = ReadDesc() ) != nbfiles )
  120.                 ListFiles(NOTFOUND);
  121.  
  122.         fclose(dfile);
  123.         if( result )
  124.         {
  125.             if( fappend( FileList,TmpFile ) )
  126.             {
  127.                     printf("Unable to update  file %s !\n",FileList );
  128.                     printf("Comments remaining in %s.\n",TmpFile);
  129.                     return(0xFF);
  130.             }
  131.  
  132.  
  133.             printf("%s",result == nbfiles ? "Update Sucessfull.\n"
  134.                         : "All new files successfully added.\n");
  135.         }
  136.         else
  137.         {
  138.           unlink(TmpFile);
  139.           printf("No file added.\n");
  140.         }
  141.         return( 0 );
  142. }
  143.  
  144. /*-------------------------------------------------------------------------*/
  145.  
  146. /*
  147.   ╒════════════════════════════════════════════════════════════════════════╕
  148.   │    FINDFILES : Creates a linked list with all the files found in the   │
  149.   │                search directory.                                       │
  150.   │                                                                        │
  151.   │                Return :  Number of files found.                        │
  152.   ╘════════════════════════════════════════════════════════════════════════╛
  153. */
  154.  
  155. int FindFiles (void)
  156. {
  157.         int i = 0 ;
  158.         static char *Pattern = "*.*" ;
  159.         static char *ErrMsg  = "Findfiles(): Cannot allocate memory for %d bytes\n";
  160.         struct Ftype *WorkStru;
  161.         int echar ;
  162.  
  163.         struct DocFile
  164.             {                                   /* My own struct since Borland  */
  165.                 char     Reserved[21];      /* and Microsoft use different  */
  166.                 char     attribut;          /* names...                     */
  167.                 unsigned Time;              /* Don't worry about warnings!  */
  168.                 unsigned Date;
  169.                 long     Taille;
  170.                 char     name[13];
  171.         }
  172.         SearchBlock;
  173.  
  174.         echar = (int) ScanDir[strlen(ScanDir) -1] ;
  175.         if( echar && echar != '\\'  && echar != '/' && echar != ':' )
  176.                 strcat(ScanDir,"\\");
  177.         strcpy(ScanPath,ScanDir);   /* Save it for later use...,   */
  178.         strcat(ScanDir,Pattern);    /* and add the search pattern. */
  179.  
  180.         Fstru = (struct Ftype *) malloc ( sizeof (struct Ftype) );
  181.         if( Fstru  == NULL )
  182.         {
  183.                 printf(ErrMsg, sizeof( struct Ftype) );
  184.                 return( 0 );
  185.         }
  186.         WorkStru = Fstru;
  187.  
  188.  
  189. #ifdef __TURBOC__
  190.         if (findfirst (ScanDir,&SearchBlock,0)  == 0)
  191. #else
  192.                 if (_dos_findfirst (ScanDir, _A_ARCH, &SearchBlock) == 0)
  193. #endif
  194.                 {
  195.                         do
  196.                             {
  197.                                 WorkStru->Next =(struct Ftype * ) NULL;
  198.                                 WorkStru->HasComment  = 0 ;
  199.                                 strcpy( WorkStru->fname, SearchBlock.name );
  200.                                 strlwr( WorkStru->fname ); /* I prefer lower case !!! */
  201.                                 i++;
  202.                                 WorkStru->Next = (struct Ftype *) malloc ( sizeof (struct Ftype) );
  203.                                 if( WorkStru->Next  == NULL )
  204.                                 {
  205.                                         printf(ErrMsg, sizeof( struct Ftype) );
  206.                                         return(i);
  207.                                 }
  208.                                 WorkStru = WorkStru -> Next;
  209.                                 WorkStru ->Next = (struct Ftype * ) NULL;
  210.                         }
  211. #ifdef __TURBOC__
  212.                         while(findnext (&SearchBlock) == 0 );
  213. #else
  214.                         while (_dos_findnext (&SearchBlock) == 0);
  215. #endif
  216.                 }
  217.                 else return 0 ;
  218.         return i ;
  219.  
  220.  
  221. }
  222. /*-------------------------------------------------------------------------*/
  223.  
  224.  
  225.  
  226. /*
  227.   ╒════════════════════════════════════════════════════════════════════════╕
  228.   │  LISTFILES:  Displays the files in the linked list.                    │
  229.   │                                                                        │
  230.   ╘════════════════════════════════════════════════════════════════════════╛
  231. */
  232.  
  233. void ListFiles(int which)
  234. {
  235.         struct Ftype *WorkStru;
  236.         int i   = 0 ;
  237.         int nb  = 0 ;
  238.  
  239.         WorkStru = Fstru ;
  240.  
  241.         if( which == ALL )
  242.                 printf("──────> Files found in %s <──────────────\n\n",ScanDir);
  243.         if( which == NOTFOUND )
  244.                 printf("──────> Files not found in %s <──────────────\n\n",FileDes);
  245.  
  246.         while( WorkStru -> Next != (struct Ftype *) NULL )
  247.         {
  248.                 if( which == ALL ||(which == NOTFOUND && ! WorkStru -> HasComment ))
  249.                 {
  250.                         printf("%-15s",WorkStru -> fname );
  251.                         i++;
  252.                         nb++;
  253.                         if( i > 4 )
  254.                         {
  255.                                 printf("\n");
  256.                                 i  = 0 ;
  257.                         }
  258.                 }
  259.                 WorkStru = WorkStru -> Next ;
  260.         }
  261.         printf("\n\n─────> %d Files.\n\n",nb);
  262. }
  263.  
  264. /*-------------------------------------------------------------------------*/
  265.  
  266. /*
  267.   ╒════════════════════════════════════════════════════════════════════════╕
  268.   │  FLAGFILE :  Moves the file in the destination directory if it is      │
  269.   │              found in the linked list,                                 │
  270.   │              Copies its description to the destination file list,      │
  271.   │              and flags the corresponding structure as commented ok.    │
  272.   │                                                                        │
  273.   │              Return :  1 if the file was in the list                   │
  274.   │                        0 if not.                                       │
  275.   ╘════════════════════════════════════════════════════════════════════════╛
  276. */
  277.  
  278. int  FlagFile(char *line )
  279. {
  280.         struct Ftype *WorkStru;
  281.  
  282.  
  283.         WorkStru = Fstru ;
  284.  
  285.         while( WorkStru -> Next != (struct Ftype *) NULL )
  286.         {
  287.                 if ( ! strnicmp (line,WorkStru-> fname,strlen(WorkStru->fname) ) )
  288.                 {
  289.                         if( MoveFile(WorkStru -> fname) )
  290.                         {
  291.                                 printf("───── Found : %s ───────────────────────\n",WorkStru -> fname );
  292.                                 PrintTab();
  293.                                 WorkStru -> HasComment = 1 ;    /* Ok files is moved. */
  294.                                 printf("─────■ File moved. ■──────────────────────"
  295.                                     "────────────────────────────────────\n\n");
  296.                                 printf("\nScanning %s..\r",FileDes);
  297.                         }
  298.                         return( 1 ); /*  Was in the list */
  299.                 }
  300.                 WorkStru = WorkStru -> Next ;
  301.         }
  302.         return( 0 );  /* Was'nt in the list */
  303. }
  304.  
  305. /*-----------------------------------------------------------------------*/
  306.  
  307.  
  308. /*
  309.   ╒════════════════════════════════════════════════════════════════════════╕
  310.   │  READDESC:   Scans the source description file, and if a file of the   │
  311.   │              linked list matches, calls FlagFile in order to process   │
  312.   │              it.                                                       │
  313.   │                                                                        │
  314.   │              Return :    Number of files found                         │
  315.   │                          0 on error.                                   │
  316.   ╘════════════════════════════════════════════════════════════════════════╛
  317. */
  318.  
  319.  
  320. int ReadDesc(void)
  321. {
  322.         FILE *fp;
  323.         char tmp[256];
  324.         int i,count = 0;
  325.  
  326.         if( (fp = fopen(FileDes,"r")) == NULL )
  327.         {
  328.                 printf("Unable to open description file %s\n",FileDes);
  329.                 return( 0 );
  330.         }
  331.         setvbuf(fp,NULL,_IOFBF,MYBUFS);
  332.  
  333.         printf("\nReading %s..\r",FileDes);
  334.  
  335.  
  336.         while(fgets(tmp,256,fp) )
  337.         {
  338.                 Clean(tmp);
  339. test_it:
  340.                 if( ! IsFilDes(tmp))  continue;   /* Search for the 1st comment line */
  341.                 else
  342.                 {
  343.                         i = 0 ;
  344.                         ClearTab();
  345.                         strcpy(CmTab[i],tmp );
  346.                         while(fgets(tmp,256,fp) )       /* read comments         */
  347.                         {
  348.                                 i++;
  349.                                 Clean(tmp);
  350.                                 if ( ! IsComment(tmp))         /* until last one        */
  351.                                 {
  352. #ifdef DEBUG
  353.                                         PrintTab();
  354. #endif
  355.                                         if( FlagFile( CmTab[0] ) )
  356.                                                 count++;
  357.                                         if( count == nbfiles) /* end of process*/
  358.                                                 return(count) ;
  359.                                         goto test_it;
  360.                                 }
  361.                                 else    strcpy(CmTab[i],tmp );
  362.                         }
  363.                 }
  364.         }
  365.  
  366.         fclose( fp );
  367.         return(count);
  368. }
  369. /*------------------------------------------------------------------------*/
  370.  
  371. /*
  372.   ╒════════════════════════════════════════════════════════════════════════╕
  373.   │   ISFILDES   : Tries to determine if the line is the 1st description   │
  374.   │                line of a file.                                         │
  375.   │                                                                        │
  376.   │                Return :  0 if it does not begin with a valid filename  │
  377.   │                          1 if it does.                                 │
  378.   │                                                                        │
  379.   │                Assumes valid names beginning column 0, containing  an  │
  380.   │                extension, and composed with ASCII characters.          │
  381.   ╘════════════════════════════════════════════════════════════════════════╛
  382. */
  383.  
  384. int IsFilDes( char *line)
  385. {
  386.         char name[15];
  387.         char *ptr;
  388.  
  389.         strncpy(name,line,12);
  390.         name[12] = 0 ;
  391.         strupr( name);
  392.  
  393.  
  394.  
  395.  
  396.         if( ! strchr(name, '.') ) return ( 0 );      /* If no extension, not */
  397.                                                      /* a filename.          */
  398.  
  399.                                                      /* If invalid chars,    */
  400.                                                      /* not a filename...    */
  401.         ptr = name;
  402.         while(*ptr)
  403.         {
  404.                 if (*ptr < 32  || *ptr > 90  )  return ( 0 );
  405.                 ptr ++;
  406.         }
  407.  
  408.         return ( 1 );
  409. }
  410. /*------------------------------------------------------------------------*/
  411.  
  412. /*
  413.   ╒════════════════════════════════════════════════════════════════════════╕
  414.   │   ISCOMMENT  : Tries to determine if the line is an additionnal        │
  415.   │                description line.                                       │
  416.   │                                                                        │
  417.   │                Return :  1 if it is one,                               │
  418.   │                          0 if not.                                     │
  419.   │                                                                        │
  420.   │                Assumes valid additionnal description lines begin with  │
  421.   │                a minimum of 30 space chars.                            │
  422.   ╘════════════════════════════════════════════════════════════════════════╛
  423. */
  424.  
  425. int IsComment(char *line)
  426. {
  427.         register int i;
  428.  
  429.         for(i=0; i < 30; i++)
  430.         {
  431.                 if (! *line)        return( 0 );
  432.                 if (*line != 32)    return( 0 );
  433.                 line++;
  434.         }
  435.  
  436.         return(1);
  437. }
  438. /*----------------------------------------------------------------------*/
  439.  
  440. /*
  441.       ┌──────────────────────────────────────────────────────┐
  442.       │   CLEAN :  Fixes the normalized bug of fgets() :-)   │
  443.       └──────────────────────────────────────────────────────┘
  444. */
  445.  
  446. void Clean( char *line)
  447. {
  448.         int i;
  449.  
  450.         i = strlen(line) - 1;
  451.  
  452.         if(line[i] == '\n');
  453.         line[i] = 0 ;
  454. }
  455. /*----------------------------------------------------------------------*/
  456.  
  457. /*
  458.       ┌──────────────────────────────────────────────────────┐
  459.       │   CLEARTAB: Cleans the comment buffer                │
  460.       └──────────────────────────────────────────────────────┘
  461. */
  462.  
  463. void ClearTab(void)
  464. {
  465.         memset (CmTab,0,MAX_C_LINES *( MAX_C_COLS + 1) );
  466. }
  467. /*---------------------------------------------------------------------*/
  468.  
  469. /*
  470.   ╒════════════════════════════════════════════════════════════════════════╕
  471.   │  PRINTTAB :  Prints the current file description on stdout, and in     │
  472.   │              the destination file list.                                │
  473.   ╘════════════════════════════════════════════════════════════════════════╛
  474. */
  475.  
  476. void PrintTab(void)
  477. {
  478.         int i;
  479.  
  480.         for( i = 0 ; CmTab[i][0]; i++)
  481.         {
  482.                 if( i ) CmTab[i][31] = '|' ;
  483.                 printf (      "%s\n",CmTab[i] );
  484.                 fprintf(dfile,"%s\n",CmTab[i] );
  485.         }
  486.  
  487. }
  488. /*--------------------------------------------------------------------------*/
  489.  
  490.  
  491. /*
  492.   ╒════════════════════════════════════════════════════════════════════════╕
  493.   │  MAKECONFPATH: Creates the full path and name of the config file,      │
  494.   │                from the argv[0] program arg.                           │
  495.   │                                                                        │
  496.   ╘════════════════════════════════════════════════════════════════════════╛
  497. */
  498.  
  499. void MakeConfPath(char *path)
  500. {
  501.         int i;
  502.  
  503.         strcpy(ConfPath,path);
  504.         i = strlen(ConfPath);
  505.         while(i)
  506.         {
  507.                 if(ConfPath[i] == '\\' || ConfPath[i] == ':') break ;
  508.                 ConfPath[i] = 0;
  509.                 i--;
  510.         }
  511.         strcpy(TmpFile,ConfPath);
  512.         strcat( ConfPath,CONFIG_FILE );
  513.         strcat( TmpFile,TMP_FILE );
  514. }
  515. /*----------------------------------------------------------------------*/
  516.  
  517.  
  518.  
  519. /*
  520.   ╒════════════════════════════════════════════════════════════════════════╕
  521.   │  READCONF:     Reads the config file.                                  │
  522.   │                Return  1 on success                                    │
  523.   │                        0 on error                                      │
  524.   ╘════════════════════════════════════════════════════════════════════════╛
  525. */
  526.  
  527.  
  528. int ReadConf(void)
  529. {
  530.         FILE *fp;
  531.         char tmp[ 256 ];
  532.         int count;
  533.  
  534.         if( (fp = fopen(ConfPath,"r")) == NULL )
  535.         {
  536.                 printf("Unable to open Config File : %s\n",ConfPath);
  537.                 printf("You must create this file before using this program...\n\n");
  538.                 SampleConfig();
  539.                 printf("A sample one has been created for you.\n");
  540.                 printf("Look at the file : %s  with  your favourite text editor  !\n",
  541.                 ConfPath);
  542.                 return(0);
  543.         }
  544.  
  545.         count = 0 ;
  546.         printf("Reading Config...\r");
  547.         while(fgets(tmp,255,fp ) )
  548.         {
  549.                 Clean(tmp );
  550.                 strupr(tmp );
  551.                 if(strlen(tmp) < 2 )        continue ;        /* Empty lines not used   */
  552.                 if(tmp[0] == COMMENT_CHAR ) continue ;        /* Commented lines..      */
  553.  
  554.                 switch( count )
  555.                 {
  556.                 case 0 :                       /* 1st line : Directory where files   */
  557.                         strcpy( ScanDir, tmp );/* are downloaded.                    */
  558.                         break  ;
  559.  
  560.                 case 1 :
  561.                         strcpy(FileDes,tmp );  /* 2nd line : Full name of the file   */
  562.                         break  ;               /* containing descriptions.           */
  563.  
  564.                 case 2 :
  565.                         strcpy(DestDir, tmp ); /* 3rd line : Destination Directory   */
  566.                         break  ;
  567.  
  568.                 case 3 :                       /* 4th line : Full name of the BBS   */
  569.                         strcpy(FileList,tmp);  /*description file to be updated     */
  570.                         break ;
  571.  
  572.  
  573.                 case 4 :                       /* 5th line : Full name of the Batch  */
  574.                         strcpy(ExtCommand,tmp);/*optionnal command                   */
  575.                         break ;
  576.                 }
  577.  
  578.                 count++ ;
  579.  
  580.                 if( count > 5 )
  581.                 {
  582.                         printf("Too many config lines !!! Invalid file...\n" );
  583.                         fclose(fp);
  584.                         return(0);
  585.                 }
  586.         }
  587.         fclose(fp);
  588.         return( 1 );
  589. }
  590. /*--------------------------------------------------------------------------*/
  591.  
  592.  
  593.  
  594. /*
  595.   ╒════════════════════════════════════════════════════════════════════════╕
  596.   │  VERIFPATH:    Verifies filenames and pathnames.                       │
  597.   │                Return  1 on success                                    │
  598.   │                        0 on error                                      │
  599.   ╘════════════════════════════════════════════════════════════════════════╛
  600. */
  601.  
  602.  
  603. int VerifPath(void)
  604. {
  605.         int RetVal = 1 ;
  606.         int echar ;
  607.  
  608.         if( access( ScanDir, 0 ) )
  609.         {
  610.                 printf("Invalid Source Directory %s\n",ScanDir );
  611.                 RetVal = 0 ;
  612.         }
  613.  
  614.         if( access( FileDes, 0 ) )
  615.         {
  616.                 printf("Invalid Filename %s\n",FileDes );
  617.                 RetVal = 0 ;
  618.         }
  619.  
  620.         if(ExtCommand[0] >32 )
  621.                 if( access( ExtCommand, 0 ) )
  622.                 {
  623.                         printf("Invalid External Command File %s\n",ExtCommand );
  624.                         RetVal = 0 ;
  625.                 }
  626.  
  627.         if( access( DestDir, 0 ) )
  628.         {
  629.                 printf("Invalid Destination Directory %s\n",DestDir );
  630.                 RetVal = 0 ;
  631.         }
  632.  
  633.          /* Prepares the Destination directory name for */
  634.          /* correct concatenation                       */
  635.  
  636.         echar = (int) DestDir[strlen(DestDir) -1] ;
  637.         if( echar && echar != '\\'  && echar != '/' && echar != ':' )
  638.                 strcat(DestDir,"\\");
  639.  
  640.          /* FileList not tested, it will be created if needed. */
  641.  
  642.         return( RetVal );
  643. }
  644. /*----------------------------------------------------------------------*/
  645.  
  646. /*
  647.   ╒════════════════════════════════════════════════════════════════════════╕
  648.   │  MOVEFILE :  Renames the file in order to have it in the destination   │
  649.   │              directory.                                                │
  650.   │              Return :       1 on success                               │
  651.   │                             0 on error                                 │
  652.   │              Doesn't use rename() in order to be able to move files    │
  653.   │              to different physical supports.                           │
  654.   ╘════════════════════════════════════════════════════════════════════════╛
  655. */
  656.  
  657. int MoveFile(char *name)
  658. {
  659.         char tmp[256];
  660.         char fullpath[256];
  661.  
  662.  
  663.         strcpy(fullpath,ScanPath);
  664.         strcat(fullpath,name   );
  665.  
  666.         if( ExtCommand[0] > 32 )
  667.         {
  668.                 sprintf(tmp,"%s %s",ExtCommand,fullpath);
  669.                 printf("Calling External Command for %s...\n",fullpath);
  670.                 /* spawnlp(P_WAIT,ExtCommand,ExtCommand,fullpath,NULL);*/
  671.                 system(tmp);
  672.         }
  673.         if (access(fullpath,0 ) )
  674.                 return ( 0 ) ;
  675.  
  676.                               /* Explanation about the above silly lines... */
  677.                               /* The User may need to process the file and  */
  678.                               /* eventually remove it or something else.    */
  679.                               /* It is impossible to use correctly a child  */
  680.                               /* process and get his return value under this*/
  681.                               /* !$&çà"é MS-DOS !!!                         */
  682.                               /* (spawn could have done it but does not work*/
  683.                               /* with batch files... )                      */
  684.                               /* So the only thing we will do is to verify  */
  685.                               /* the acces to the file , and pray... :-)    */
  686.  
  687.         RealStat(fullpath,name);  /* Date or size may have been modified... */
  688.         strcpy( tmp,DestDir );
  689.         strcat(tmp,name);
  690.  
  691.         if( fmove(fullpath,tmp) )
  692.         {
  693.                 printf("Unable to move %s to %s !\n", fullpath,tmp );
  694.                 return( 0 );
  695.         }
  696.         return ( 1 );
  697. }
  698. /*------------------------------------------------------------------------*/
  699.  
  700.  
  701. /*
  702.   ╒════════════════════════════════════════════════════════════════════════╕
  703.   │  FMOVE    :  Moves source File to dest File, using a fast copy routine │
  704.   │                                                                        │
  705.   │              Return :       0 on success                               │
  706.   │                             1 on error                                 │
  707.   ╘════════════════════════════════════════════════════════════════════════╛
  708. */
  709.  
  710. fmove(char *source, char *destin)
  711. {
  712.         int src,
  713.         dst;
  714.         int perm = S_IREAD | S_IWRITE ;
  715.         int acc  = O_RDWR | O_BINARY | O_CREAT | O_TRUNC ;
  716.         int nb;
  717.         char buf[MYBUFS];
  718.  
  719. #ifdef __TURBOC__
  720.         struct ftime df;
  721. #else
  722.         unsigned df,
  723.         tf;
  724. #endif
  725.  
  726.  
  727.         if(  ( src  = open (source,O_RDONLY | O_BINARY) ) == -1 )
  728.         {
  729.                 printf("Unable to read file %s\n",source );
  730.                 return( 1 );
  731.         }
  732. #ifdef __TURBOC__
  733.         getftime(src,&df);            /* Get the original file date !   */
  734. #else
  735.         _dos_getftime(src,&df,&tf);
  736. #endif
  737.  
  738.  
  739.  
  740.         if(  ( dst  = open (destin,acc,perm) ) == -1 )
  741.         {
  742.                 printf("Unable to create file %s\n",source );
  743.                 Perror("System Report");
  744.                 return( 1 );
  745.         }
  746.  
  747.         while( (nb  = read ( src, buf, MYBUFS )) )
  748.                 write( dst,buf,nb );
  749.  
  750. #ifdef __TURBOC__
  751.         setftime(dst,&df);            /* Set the original file date !  */
  752. #else
  753.         _dos_setftime(dst,df,tf);
  754. #endif
  755.  
  756.         close( src );
  757.         close( dst );
  758.  
  759.         if( unlink(source) == -1 )
  760.         {
  761.                 printf("Unable to remove %s !\n", source );
  762.                 Perror("System Report");
  763.                 /* Not a real error,return OK. */
  764.         }
  765.         return( 0 );
  766. }
  767. /*-----------------------------------------------------------------------*/
  768.  
  769.  
  770. /*
  771.   ╒════════════════════════════════════════════════════════════════════════╕
  772.   │  FAPPEND  :  Appends source File to dest File, trying to manage with   │
  773.   │              sharing errors,I don't understand why this doesn't work   │
  774.   │              like in  **IX systems whith C-language and DOS!           │
  775.   │              Here is a quick & dirty method... But I do not want to    │
  776.   │              waste time learning  those specific stuff which I'll      │
  777.   │              never use... :-)                                          │
  778.   │                                                                        │
  779.   │              Removes Source file on succes.                            │
  780.   │                                                                        │
  781.   │              Return :       0 on success                               │
  782.   │                             1 on error                                 │
  783.   ╘════════════════════════════════════════════════════════════════════════╛
  784. */
  785.  
  786.  
  787. int fappend(char *destin, char *source )
  788. {
  789.         int src,dst,
  790.         try = 10,
  791.         nb,result;
  792.         char buf[ MYBUFS ];
  793.  
  794.         printf("Updating file %s...\n",destin);
  795.  
  796.         if(  ( src = open( source, O_RDONLY | O_BINARY ) ) == -1 )
  797.         {
  798.                 printf("Error opening file %s !\n",source);
  799.                 return ( 1 );
  800.         }
  801.  
  802.         while( try-- )
  803.         {
  804.                 dst = sopen( destin,
  805.                              O_RDWR | O_APPEND | O_CREAT | O_BINARY,
  806.                              SH_DENYWR , S_IWRITE );
  807.                 if( dst == - 1 )
  808.                 {
  809.                         switch( errno )
  810.                         {
  811.                         case EMFILE  :
  812.                                 printf(" Too many files opened !!!!!!! "
  813.                                     " Check your system configuration !!!\n");
  814.                                 return( 1 );
  815.  
  816.                         case EACCES  :
  817.                                 if( try < 1 ) return (1);
  818.                                 printf("File busy...?  Try %d\r",10 - try );
  819.                                 sleep( 2 );   /* Wait 2 seconds */
  820.                                 break ;
  821.  
  822.                         default :
  823.                                 Perror("System Report") ;
  824.                                 return ( 1 );
  825.                         }
  826.                 }
  827.                 else break ;        /* File sucessfully opened */
  828.         }
  829.  
  830.  
  831.         while( (nb = read ( src, buf, MYBUFS ) ) )
  832.         {
  833.                 result = write( dst,buf,nb );
  834.                 if( result == -1 )
  835.                 {
  836.                         printf("Error Writing file %s !\n",destin);
  837.                         close  ( src );
  838.                         close  ( dst );
  839.                         return (  1  );
  840.                 }
  841.         }
  842.  
  843.         close ( src );
  844.         close ( dst );
  845.         if ( unlink(source) != 0 )
  846.         {
  847.                 printf("Unable to remove %s : ",source);
  848.                 Perror("");
  849.                 return( 1 );
  850.         }
  851.         return ( 0 ) ;
  852. }
  853.  
  854.  
  855. /*
  856.    ╒════════════════════════════════════════════════════════════════════════╕
  857.    │  REALSTAT :  Puts the real date & size of the filename in  the comment.│
  858.    │                                                                        │
  859.    ╘════════════════════════════════════════════════════════════════════════╛
  860. */
  861.  
  862. #define C_OFFSET 33      /* Comment text seems to begin at column 33 ... */
  863.  
  864. void RealStat(char *fullpath,char *name)
  865. {
  866.         struct stat  st  ;
  867.         struct tm   *tim ;
  868.         char comment[256];
  869.         int i;
  870.  
  871.         for( i = 0; CmTab[0][i + C_OFFSET] ; i++ )
  872.                 comment[i] = CmTab[0][i+ C_OFFSET];
  873.         comment[i] = 0;
  874.  
  875.         /* Comment text seems to begin at column C_OFFSET ... */
  876.         /* Save it, and take the real file stats              */
  877.  
  878.         stat(fullpath ,&st);
  879.         tim = gmtime( &st.st_atime );
  880.         sprintf(CmTab[0],"%-12s  %7ld  %02d-%02d-%02d  %s",
  881.         strupr(name),
  882.         st.st_size,
  883.         tim->tm_mon +1,
  884.         tim->tm_mday,
  885.         tim->tm_year,
  886.         comment);
  887.  
  888.         /* I don't test the COUNTRY variable in **environ, this is */
  889.         /* The US date format...                                   */
  890. }
  891. /*--------------------------------------------------------------------------*/
  892.  
  893.  
  894. /*
  895.  ╒════════════════════════════════════════════════════════════════════════╕
  896.  │  PERROR :   Perror() is a replacement for perror(),writing on stdout   │
  897.  │             instead of stderr.                                         │
  898.  ╘════════════════════════════════════════════════════════════════════════╛
  899. */
  900. void Perror(char *s)
  901. {
  902.         printf("%s :    %s\n",s,sys_errlist[errno] );
  903. }
  904. /*------------------------------------------------------------------------*/
  905.  
  906. #ifndef __TURBOC__
  907. /*
  908.  ╒════════════════════════════════════════════════════════════════════════╕
  909.  │  SLEEP  :   quick implementation of function sleep(), non existent     │
  910.  │             in Microsoft - C... !!!!                                   │
  911.  ╘════════════════════════════════════════════════════════════════════════╛
  912. */
  913. sleep(unsigned  sec)
  914. {
  915.         long t1,t2;
  916.  
  917.         time (&t1);
  918.         t2 = t1;
  919.         t1+= (long) sec;
  920.         while( t2 < t1 )
  921.                 time (&t2 );
  922. }
  923. /*------------------------------------------------------------------------*/
  924. #endif
  925.  
  926. /*
  927.   ╒════════════════════════════════════════════════════════════════════════╕
  928.   │  SAMPLECONFIG: Creates a sample configuration file if possible.        │
  929.   │                                                                        │
  930.   ╘════════════════════════════════════════════════════════════════════════╛
  931. */
  932.  
  933. void SampleConfig(void)
  934. {
  935.         FILE *fp;
  936.  
  937.  
  938.         if( (fp = fopen(ConfPath,"w")) == NULL ) return ;
  939.  
  940.         fprintf(fp,"#----------------------------------------------------------\n");
  941.         fprintf(fp,"# This is a sample configuration file for ADD2BBS.EXE.     \n");
  942.         fprintf(fp,"# Replace the pathnames & directories by your own values.  \n");
  943.  
  944.         fprintf(fp,"#----------------------------------------------------------\n");
  945.         fprintf(fp,"# Below is the name of the directory where the program     \n");
  946.         fprintf(fp,"# will look for the files you want to move :               \n");
  947.         fprintf(fp,"#\n\n");
  948.         fprintf(fp,"C:\\FILE2MOV\n\n");
  949.         fprintf(fp,"#\n");
  950.  
  951.         fprintf(fp,"#----------------------------------------------------------\n");
  952.         fprintf(fp,"# Below is the Full Name and Pathname of the file          \n");
  953.         fprintf(fp,"# containing the descriptions corresponding to the files : \n");
  954.         fprintf(fp,"#\n\n");
  955.         fprintf(fp,"C:\\FIL2MOVE\\INPUT.DSC\n\n");
  956.         fprintf(fp,"#\n");
  957.  
  958.         fprintf(fp,"#----------------------------------------------------------\n");
  959.         fprintf(fp,"# Now, the directory where you want to move the files to:  \n");
  960.         fprintf(fp,"#\n\n");
  961.         fprintf(fp,"C:\\FILMOVED\n\n");
  962.         fprintf(fp,"#\n");
  963.  
  964.         fprintf(fp,"#----------------------------------------------------------\n");
  965.         fprintf(fp,"# Here, the full Name and Pathname of the description      \n");
  966.         fprintf(fp,"# file you want to update or create :\n");
  967.         fprintf(fp,"#\n\n");
  968.         fprintf(fp,"C:\\FIL2MOVE\\OUTPUT.DSC\n\n");
  969.         fprintf(fp,"#\n");
  970.         fprintf(fp,"#----------------------------------------------------------\n");
  971.  
  972.         fprintf(fp,"# Finally the full pathname of an optionnal batch file,\n");
  973.         fprintf(fp,"#\n");
  974.         fprintf(fp,"# It will be called by the program with the current\n");
  975.         fprintf(fp,"# filename as argument ( e.g ' TESTFIL.BAT 2BEMOVED.ZIP')\n");
  976.         fprintf(fp,"# just BEFORE moving the file.\n");
  977.         fprintf(fp,"#\n");
  978.         fprintf(fp,"# (This can be used to SCAN a ZIP file for virii,        \n");
  979.         fprintf(fp,"# remove a ZIP comment, add a new one, etc ...)          \n");
  980.         fprintf(fp,"#\n");
  981.         fprintf(fp,"# Leave this field blank if no special processing needed.\n");
  982.         fprintf(fp,"#\n\n");
  983.         fprintf(fp,"TESTFILE.BAT\n\n");
  984.         fprintf(fp,"#\n");
  985.         fprintf(fp,"#----------------------------------------------------------\n");
  986.  
  987.         fclose(fp);
  988. }
  989. /*------------------------------------------------------------------------*/
  990.  
  991.  
  992. void Usage(void)
  993. {
  994.         printf("Usage : ADD2BBS source_dir source_list dest_dir dest_list\n\n");
  995.         printf("        Configuration file is used if no argument.\n");
  996. }
  997. /*------------------------------------------------------------------------*/
  998.  
  999. void Title(void )
  1000. {
  1001.         printf(
  1002.             "\t\t╒═════════════════════════════════════════╕\n"
  1003.             "\t\t│ Add2bbs: Public Domain PcBoard Utility  │\n"
  1004.             "\t\t│    by René COUGNENC & Attila ALTAN      │\n"
  1005.             "\t\t│            France - 1990                │\n"
  1006.             "\t\t╘═══════════════════════════════════[%3s]═╛\n"
  1007.             "\n", ___VERSION___
  1008.             );
  1009. }
  1010. /*-------------------------------------------------------------------------*/
  1011.  
  1012.  
  1013. /*=====================( End of add2bbs.C )================================*/
  1014.  
  1015.  
  1016. #ifdef NOT_USED_PERHAPS_ONE_DAY
  1017.  
  1018.  /*
  1019.    ╒════════════════════════════════════════════════════════════════════════╕
  1020.    │  LASTFILES:  Scans the linked list for the undescribed files.          │
  1021.    │              Moves them to the destination directory, and write an     │
  1022.    │              empty comment to the destination description file.        │
  1023.    │                                                                        │
  1024.    ╘════════════════════════════════════════════════════════════════════════╛
  1025.  
  1026. */
  1027.  
  1028.  
  1029. void LastFiles(void)
  1030. {
  1031.         struct Ftype *WorkStru;
  1032.         struct stat  st  ;
  1033.         struct tm   *tim ;
  1034.  
  1035.         WorkStru = Fstru ;
  1036.  
  1037.         while( WorkStru -> Next != (struct Ftype *) NULL )
  1038.         {
  1039.                 if (! WorkStru->HasComment )
  1040.                 {
  1041.                         stat(WorkStru -> fname ,&st);
  1042.                         tim = gmtime( &st.st_atime );
  1043.                         sprintf(CmTab[0],"%-12s  %7ld  %02d-%02d-%02d  %s",
  1044.                         strupr(WorkStru->fname),
  1045.                         st.st_size,
  1046.                         tim->tm_mon +1,
  1047.                         tim->tm_mday,
  1048.                         tim->tm_year,
  1049.                         NullComment);
  1050.                         CmTab[1][0] = 0;
  1051.                         if( MoveFile( WorkStru -> fname ) )
  1052.                         {
  1053.                                 printf("───── Not Found : %s ───────────────────────\n",WorkStru -> fname );
  1054.                                 PrintTab();
  1055.                                 printf("----- File moved.---------------------------\n");
  1056.                         }
  1057.                 }
  1058.                 WorkStru = WorkStru -> Next ;
  1059.         }
  1060. }
  1061. /*--------------------------------------------------------------------------*/
  1062. #endif
  1063.